package com.wf.demo.info.service;

import com.alibaba.fastjson.JSONObject;
import com.wf.demo.info.dao.CompanyDAO;
import com.wf.demo.info.dao.DeviceDAO;
import com.wf.demo.info.dao.ModelDAO;
import com.wf.demo.info.pojo.Company;
import com.wf.demo.info.pojo.Model;
import com.wf.demo.info.util.Page4Navigator;
import com.wf.demo.job.service.DeviceNumberChangeOfCompanyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
@Slf4j
@Service
@CacheConfig(cacheNames = "companys")
public class CompanyService {
    @Autowired
    CompanyDAO companyDAO;
    @Autowired
    DeviceDAO deviceDAO;
    @Autowired
    DeviceNumberChangeOfCompanyService deviceNumberChangeOfCompanyService;
    @Autowired
    ModelDAO modelDAO;
    @Cacheable(key="'companys-page-'+#p0+ '-' + #p1")
    public Page4Navigator<Company> list(int start, int size, int navigatePages) {
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(start, size, sort);
        Page pageFromJPA = companyDAO.findAll(pageable);
        return new Page4Navigator<>(pageFromJPA, navigatePages);
    }
    @Cacheable(key="'companys-all'")
    public List<Company> list(){
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return companyDAO.findAll(sort);
    }
    @CacheEvict(allEntries = true)
    public void delete(int id){
        companyDAO.delete(id);
    }
     @CacheEvict(allEntries = true)
    public void update(Company bean){
        companyDAO.save(bean);
    }
    @CacheEvict(allEntries = true)
    public void add(Company bean){
        companyDAO.save(bean);
    }

    @Cacheable(key="'companys-one-'+ #p0")
    public Company get(int id){
        return  companyDAO.findOne(id);
    }


    public boolean isExist(String name) {
       Company company= companyDAO.findByName(name);
        return null!=company;
    }
    public boolean isExist(Company bean) {
        //找到id
        int  id =bean.getId();
        //先得到对应id的对象在数据库的名字
        String oldName=companyDAO.getOne(id).getName();
        String name=bean.getName();
        //如果名字没改变
        if (oldName.equals(name)){
            return false;
        }
        Company company= companyDAO.findByName(name);
        return null!=company;
    }
    /**
     *功能描述 根据具体厂家进行总数量的统计（数量随时间（月）的变化情况）
     * 统计最近一年的
     * @author wf
     * @date 2019/12/12
     * @param company
     * @return java.lang.Object
     */
    public Object  getCompanyChange(Company company){
        //得到总数量
        int totalNumberOfCompany= Math.toIntExact(deviceDAO.countByCompany(company));
        int[] dataChange=new int[12]; //数量变化数组
        int numberOfMonth=0;
        //过去一年的月份
        //创建一个hashMap来储存   LinkedHashMap 可以按顺序读出读入
        Map<String,Integer> map= new LinkedHashMap<>();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        /**统计本月变化情况**/
        //获取本月第一天
        LocalDate firstDayThisMonth = LocalDate.now().withDayOfMonth(1);
        //获取本月第一天零点
        LocalDateTime today_startOfMonth = LocalDateTime.of(firstDayThisMonth, LocalTime.MIN);
        //获取现在的时间
        LocalDateTime localDateTimeNow=LocalDateTime.now();
        //若公司创建的时间在当月，即本月第一天零点之后
        if(company.getCreateTime().isAfter(today_startOfMonth)){

            dataChange[0]=deviceNumberChangeOfCompanyService.searchCompanyMonthData(company.getCreateTime(),localDateTimeNow,company);

            if(dataChange[0] == 99999)
                dataChange[0]=0;  //99999意味着该月没有任何添加和删除设备的操作,也有可能是该月公司还没有创建
            log.info("dataChange[0]"+dataChange[0]);
             numberOfMonth= (totalNumberOfCompany-dataChange[0]);

            //今天的日期和设备总数量
            map.put(df.format(localDateTimeNow),totalNumberOfCompany);
            //统计公司创建的时间第一天的设备数量
            map.put(df.format(company.getCreateTime()), numberOfMonth);

            /***后面的程序不需要再执行了**********/
            return  map;
        }
        else{
            //本月第一天零点截止到现在的数量变化
            dataChange[0]=deviceNumberChangeOfCompanyService.searchCompanyMonthData(today_startOfMonth,localDateTimeNow,company);
            if(dataChange[0] == 99999)
                dataChange[0]=0;  //99999意味着该月没有任何添加和删除设备的操作
            log.info("dataChange[0]"+dataChange[0]);
             numberOfMonth= (totalNumberOfCompany-dataChange[0]);

            //今天的日期和设备总数量
            map.put(df.format(localDateTimeNow),totalNumberOfCompany);
            //统计截止这个月第一天的设备数量
            map.put(df.format(firstDayThisMonth), numberOfMonth);
        }



        /*********统计前一年的的变化情况********/
         //根据一个月的第一天日期得到这个月的起始和结束  11个月
        for(int i=1;i<12;i++){
            LocalDate past1Month=firstDayThisMonth.plusMonths(-i);  //上个月的第一天
            LocalDateTime  start_past1Month = LocalDateTime.of(past1Month, LocalTime.MIN);  //上个月的第一天的零点
            LocalDate  lastDay_past1Month =past1Month.with(TemporalAdjusters.lastDayOfMonth()); //上个月的最后一天
            LocalDateTime end_past1Month =LocalDateTime.of(lastDay_past1Month,LocalTime.MAX);//上个月的最后一天的零点

            //若公司创建的时间在这个月name，计算完后就跳出循环
            if (company.getCreateTime().isAfter(start_past1Month) && company.getCreateTime().isBefore(end_past1Month)){
                    //  统计从公司创建时间到月末的设备数量变化情况
                dataChange[i]=deviceNumberChangeOfCompanyService.searchCompanyMonthData(company.getCreateTime(),end_past1Month,company);

                if(dataChange[i] == 99999)
                    dataChange[i]=0;  //99999意味着该月没有任何添加和删除设备的操作

                log.info("dataChange"+i+dataChange[i]);
                numberOfMonth= (int) (numberOfMonth-dataChange[i]);

                map.put(df.format(company.getCreateTime()),numberOfMonth);
                break;
            }
            else{
                dataChange[i]=deviceNumberChangeOfCompanyService.searchCompanyMonthData(start_past1Month,end_past1Month,company);

                System.out.println("月变化量为"+dataChange[i]);
                if(dataChange[i] == 99999)
                    dataChange[i]=0;  //99999意味着该月没有任何添加和删除设备的操作,也有可能是该月公司还没有创建

                log.info("dataChange"+i+dataChange[i]);
                numberOfMonth= (int) (numberOfMonth-dataChange[i]);

                map.put(df.format(past1Month),numberOfMonth);
            }

        }
        return  map;
    }
    /**
     *功能描述  设备总数xx，A厂xx，B厂xx，C厂xx
     *                      A厂某型号xx
     * @author wf
     * @date 2019/12/23
     * @param
     * @return java.lang.Object
     */
    public  Object statisticDeviceAndCompany(){
        List<Company> companies=companyDAO.findAll();
        List<Model> models =modelDAO.findAll();
       LinkedHashMap<String, Object> map=new LinkedHashMap<>();
        //每个公司设备总数量
        long totalNumber =0;
        //每个公司某种机型设备数量
        long number=0;

        for(Company company:companies){
            //用来储存每个公司的信息
            LinkedHashMap<String ,Object> obj =new LinkedHashMap<>();
            //统计总数量
            totalNumber = deviceDAO.countByCompany(company);
            obj.put("totalNumber",totalNumber);
            //统计该公司下每种设备的机型数量
            for (Model model: models){
                number=deviceDAO.countByCompanyAndModel(company,model);
                //如果数量不为0
                if (number !=0)
                    obj.put(model.getModelName(),number);
                }
            //从DeviceNumberChangeOfCompany得到一个公司设备数量最近12个月的变化情况
            obj.put("deviceChange",getCompanyChange(company));
            //对一个公司的信息储存
            map.put(company.getName(),obj);
        }
            return  map;
    }
}
